package cn.topcodes.tcsf.admin.commons.query;

import cn.topcodes.tcsf.admin.commons.domain.Page;
import tk.mybatis.mapper.entity.Example;
import java.util.List;
import java.util.Map;

/**
 * 单表/视图 查询服务接口
 * @author unicorn
 *
 * @param <T>	实体对象泛型
 */
public interface IQueryService<T> {
	
	/**
	 * 构建一个查询条件对象
	 * @return	查询条件对象
	 */
	Example buildExample();
	
	/**
	 * 统计记录总数
	 * @return	记录总数
	 */
	int countAll();
	
	/**
	 * 通过查询条件查询记录数量
	 * @param example	记录数量
	 * @return	记录数量
	 */
	int count(Example example);
	
	/**
	 * 根据ID查找实体
	 * @param id	实体ID
	 * @return		实体对象
	 */
	T findOne(Long id);

	/**
	 * 根据ID查找实体
	 * 查找不到则抛出EntityNotFoundException
	 * @param id	实体ID
	 * @return		实体对象
	 */
	T findOneOrFail(Long id);
	
	/**
	 * 通过查询条件查询实体
	 * @param example	查询条件
	 * @return			实体对象
	 */
	T findOne(Example example);

	/**
	 * 通过查询条件查询实体
	 * 查找不到则抛出EntityNotFoundException
	 * @param example	查询条件
	 * @return			实体对象
	 */
	T findOneOrFail(Example example);
	
	/**
	 * 查询所有实体
	 * @return	实体列表
	 */
	List<T> findAll();
	
	/**
	 * 通过查询条件查询所有实体
	 * @param example	查询条件
	 * @return			实体列表
	 */
	List<T> findAll(Example example);
	
	/**
	 * 通过查询条件查询所有实体
	 * @param searchParams	查询条件，前端可以根据灵活的规则自定义查询条件
	 * @return	实体列表
	 */
	List<T> findAll(Map<String,String[]> searchParams);
	
	/**
	 * 分页组合条件查询所有实体
	 * @param example		查询条件
	 * @param pageNumber	页号
	 * @param pageSize		每页条数
	 * @return				分页数据
	 */
	Page<T> findPage(Example example, int pageNumber, int pageSize);
	
	/**
	 * 分页组合条件查询所有实体
	 * @param searchParams	查询条件，前端可以根据灵活的规则自定义查询条件
	 * @param pageNumber	页号
	 * @param pageSize		每页条数
	 * @return				分页数据
	 */
	Page<T> findPage(Map<String,String[]> searchParams, int pageNumber, int pageSize);

	/**
	 * 判断除了指定ID，是否存在相同属性值相同的记录
	 * @param id
	 * @param property
	 * @param value
	 * @return
	 */
	boolean exist(Long id, String property, Object value);

	/**
	 * 判断指定ID记录是否存在
	 * @param id	ID
	 * @return
	 */
	boolean exist(Long id);

	/**
	 * 判断属性值是否存在
	 * @param property 属性名称
	 * @param value	属性值
	 * @return
	 */
	boolean exist(String property, Object value);

	/**
	 * 根据条件判断是否存在
	 * @param example
	 * @return
	 */
	boolean exist(Example example);
	
	/**
	 * 获取实体类的Class
	 * @return	Class对象
	 */
	Class<T> getEntityClass();
}
